﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using Telerik.WinControls;
using Telerik.WinControls.UI;
using Aspose.Cells;
using System.IO;

namespace UnigenReport.Form
{
    public partial class ucWorldOrder : UserControl
    {
        private UnigenDataContext db;

        #region Thiết lập

        public ucWorldOrder()
        {
            InitializeComponent();
            //Phân quyền
            if (Variables.UserRoleID == 0)
            {
                btnDelete.Visibility =
                btnImport.Visibility =
                btnExportTemp.Visibility = ElementVisibility.Collapsed;
            }
            SetEvent();
            Common.SetMenuShortcut(btnInsert, btnUpdate, btnDelete, btnGetData, btnCloseForm);
            cboClosed.SelectedIndex = 1;
            cboListSize.SelectedIndex = 1;
        }

        /// <summary>
        /// Khai báo các sự kiện
        /// </summary>
        private void SetEvent()
        {
            this.Load += OnLoad;
            this.btnInsert.Click += new System.EventHandler(this.btnInsert_Click);
            this.btnUpdate.Click += new System.EventHandler(this.btnUpdate_Click);
            this.btnDelete.Click += new System.EventHandler(this.btnDelete_Click);
            this.btnGetData.Click += new System.EventHandler(this.btnGetData_Click);
            this.btnImport.Click += new System.EventHandler(this.btnImport_Click);
            this.btnExportTemp.Click += new System.EventHandler(this.btnExportTemp_Click);
            this.btnCloseForm.Click += new System.EventHandler(this.btnCloseForm_Click);
            this.btnSaveImport.Click += new System.EventHandler(this.btnSaveImport_Click);
            this.btnCancelImport.Click += new System.EventHandler(this.btnCancelImport_Click);
            this.btnSearch.Click += new System.EventHandler(this.btnSearch_Click);
            this.btnExport.Click += new System.EventHandler(this.btnExport_Click);
            this.btnPrint.Click += new System.EventHandler(this.btnPrint_Click);
            this.grvWO.CellDoubleClick += new Telerik.WinControls.UI.GridViewCellEventHandler(this.grvWO_CellDoubleClick);        
        }

        /// <summary>
        /// Hàm load form
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnLoad(object sender, EventArgs e)
        {
            //Load default
            SetDefault();
        }

        /// <summary>
        /// Thiết lập các giá trị mặc định của form
        /// </summary>
        private void SetDefault()
        {
            //Bind dữ liệu chính
            BindData();
        }

        /// <summary>
        /// Lấy dữ liệu chính
        /// </summary>
        private void BindData()
        {
            //Data bind
            var size = Convert.ToInt32(cboListSize.Text);

            sourceWO.DataSource = GetData(size);

            //STT
            Common.SetNo(grvWO);
        }

        private List<WorldOrder> GetData(int size = 65000)
        {
            db = new UnigenDataContext();
            var sizeCondition = string.Empty;
            if (cboListSize.SelectedIndex > 0)
                sizeCondition += " TOP " + size;
            var whereCondition = " wo.Active = 1";
            var wo = txtWo.Text.Trim();

            if (!String.IsNullOrEmpty(wo))
            {
                var noCondition = new List<string>();
                foreach (var str in wo.Split(','))
                    noCondition.Add(" wo.WO LIKE N'%" + str + "%'");

                whereCondition += " AND (" + String.Join(" OR", noCondition) + ")";
            }
            if (cboClosed.SelectedIndex == 1)
                whereCondition += " AND ISNULL(wo.Closed,0) = 0";
            else if (cboClosed.SelectedIndex == 2)
                whereCondition += " AND ISNULL(wo.Closed,0) = 1";

            return db.ExecuteQuery<WorldOrder>(String.Format("SELECT {0} * FROM WorldOrder wo WHERE {1} ORDER BY wo.WO DESC"
                , sizeCondition, whereCondition)).ToList();
        }

        #endregion

        #region Hàm

        private void Insert()
        {
            try
            {
                var newItem = new Form.ucWorldOrderEdit() { Dock = DockStyle.Fill };
                var ui = Common.CreateForm(newItem, String.Empty, 480, 330);

                if (ui.ShowDialog() == DialogResult.OK)
                {
                    BindData();
                    Common.ShowSaveSuccess();
                }
            }
            catch (Exception ex)
            {
                Common.ShowErrorMess("Insert - " + ex.Message);
            }
        }

        private void Update()
        {
            try
            {
                if (sourceWO.Current == null)
                {
                    Common.ShowSelectionRequire();
                    return;
                }

                db = new UnigenDataContext();
                var selectedWO = sourceWO.Current as WorldOrder;
                var newestWO = db.WorldOrders.SingleOrDefault(p => p.WOId == selectedWO.WOId);

                var itemEdit = new Form.ucWorldOrderEdit() { Dock = DockStyle.Fill }.ForUpdate(newestWO);
                var ui = Common.CreateForm(itemEdit, String.Empty, 480, 330);

                if (ui.ShowDialog() == DialogResult.OK)
                {
                    BindData();
                    Common.ShowSaveSuccess();
                }
            }
            catch (Exception ex)
            {
                Common.ShowErrorMess("Update - " + ex.Message);
            }
        }

        private void Delete()
        {
            try
            {
                if (sourceWO.Current == null)
                {
                    Common.ShowSelectionRequire();
                    return;
                }
                db = new UnigenDataContext();
                var inputItem = (sourceWO.Current as WorldOrder);
                if (inputItem.Closed ?? false)
                {
                    Common.ShowNoticeMess("Không thể xóa WO đã đóng!");
                    return;
                }
                if (Common.ShowQuestion("Xóa wo " + inputItem.WO + " ?") != DialogResult.OK)
                    return;

                var removeItem = db.WorldOrders.SingleOrDefault(p => p.WOId == inputItem.WOId);
                //Xóa
                db.WorldOrders.DeleteOnSubmit(removeItem);
                db.SubmitChanges();

                //Remove khỏi grid
                sourceWO.Remove(inputItem);
                Common.SetNo(grvWO);

                //Thông báo
                Common.ShowSaveSuccess();
            }
            catch (Exception ex)
            {
                Common.ShowErrorMess("Delete - " + ex.Message);
            }
        }

        private void SetImportState(bool isImport)
        {
            if (isImport)
            {
                cmbImport.Visibility = ElementVisibility.Visible;
                cmbMenu.Enabled = btnSearch.Enabled = txtWo.Enabled = cboClosed.Enabled = cboListSize.Enabled = false;
                grvWO.CellDoubleClick -= grvWO_CellDoubleClick;                    
            }
            else
            {
                cmbImport.Visibility = ElementVisibility.Collapsed;
                cmbMenu.Enabled = btnSearch.Enabled = txtWo.Enabled = cboClosed.Enabled = cboListSize.Enabled = true;
                grvWO.CellDoubleClick += grvWO_CellDoubleClick;
            }
        }

        private void ExportFile(List<WorldOrder> data, string fileName, int exportType)
        {
            try
            {
                //datacontext
                db = new UnigenDataContext();

                //Tạo một đối tượng workbook
                var stream = new MemoryStream(global::UnigenReport.Properties.Resources.WorldOrderReport);
                var workbook = new Workbook(stream);

                var cells = workbook.Worksheets[0].Cells;
                var rowIndex = 2;

                if (data.Count > 1)
                    cells.InsertRows(2, data.Count - 1);

                //Bắt đầu đổ dữ liệu
                for (var i = 0; i < data.Count; i++)
                {
                    var item = data[i];

                    //Cột STT
                    cells["A" + rowIndex].PutValue(i + 1);
                    cells["B" + rowIndex].PutValue(item.WO);
                    cells["C" + rowIndex].PutValue(item.PO);
                    cells["D" + rowIndex].PutValue(item.SO);
                    cells["E" + rowIndex].PutValue(item.Product.ProductCode);
                    cells["F" + rowIndex].PutValue(item.Product.ProductName);
                    cells["G" + rowIndex].PutValue(item.Ordered);
                    cells["H" + rowIndex].PutValue(item.Shipped);
                    cells["I" + rowIndex].PutValue(item.Debit);
                    cells["J" + rowIndex].PutValue(item.Remained);
                    cells["K" + rowIndex].PutValue(item.Closed == true ? "CLOSED" : String.Empty);

                    rowIndex++;
                }

                try
                {
                    workbook.Save(fileName);

                    //Mở file Excel vừa lưu
                    if (exportType == 0) //Xuất excel
                    {
                        System.Diagnostics.Process.Start(fileName);
                    }
                    else //In
                    {
                        var config = new SystemConfig.UserConfig();
                        Common.PrintExcelAuto(fileName, config.PrintCopies);
                    }
                }
                catch (Exception ex)
                {
                    Common.ShowErrorMess("ExportFile - " + ex.Message);
                    return;
                }
            }
            catch (Exception ex)
            {
                Common.ShowErrorMess("ExportFile - " + ex.Message);
                return;
            }
        }

        #endregion
        
        #region Sự kiện

        protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
            if (keyData == Keys.Enter && cmbImport.Visibility == ElementVisibility.Collapsed)
            {
                BindData();
            }
            return base.ProcessCmdKey(ref msg, keyData);
        }

        private void btnInsert_Click(object sender, EventArgs e)
        {
            Insert();
        }

        private void btnUpdate_Click(object sender, EventArgs e)
        {
            Update();
        }

        private void btnDelete_Click(object sender, EventArgs e)
        {
            Delete();
        }

        private void btnGetData_Click(object sender, EventArgs e)
        {
            BindData();
        }

        private void btnImport_Click(object sender, EventArgs e)
        {
            try
            {
                //Chon file
                var openFileDialog = new OpenFileDialog();

                if (openFileDialog.ShowDialog() != DialogResult.OK)
                {
                    return;
                }

                if (openFileDialog.FileName.Equals(String.Empty))
                {
                    return;
                }

                var fileName = openFileDialog.FileName;

                //Import
                var workbook = new Workbook(fileName);
                var woCells = workbook.Worksheets[0].Cells;

                var lstImportWO = new List<WorldOrder>();
                var success = true;
                var row = 2;
                var error = String.Empty;
                while (woCells["B" + row].Value != null)
                {
                    var wo = new WorldOrder();
                    wo.WO = (woCells["B" + row].Value ?? "").ToString();
                    if (String.IsNullOrEmpty(wo.WO) || db.WorldOrders.Count(p => p.WO == wo.WO) > 0 || lstImportWO.Count(p => p.WO == wo.WO) > 0)
                    {
                        error = "Mã " + wo.WO + " đã tồn tại trong hệ thống hoặc trùng trong file";
                        success = false;
                        break;
                    }
                    wo.PO = (woCells["C" + row].Value ?? "").ToString();
                    wo.SO = (woCells["D" + row].Value ?? "").ToString();
                    var product = db.Products.SingleOrDefault(p => p.ProductCode == (woCells["E" + row].Value ?? "").ToString());
                    if (product == null)
                    {
                        error = "Mã hàng " + (woCells["E" + row].Value ?? "").ToString() + " (dòng " + row + ")  không tồn tại";
                        success = false;
                        break;
                    }
                    //wo.ProductId = product.ProductId;
                    wo.Product = product;
                    int ordered = 0;
                    int shipped = 0;
                    int debit = 0;
                    int remained = 0;
                    int.TryParse((woCells["F" + row].Value ?? "").ToString(), out ordered);
                    int.TryParse((woCells["G" + row].Value ?? "").ToString().ToString(), out shipped);
                    int.TryParse((woCells["H" + row].Value ?? "").ToString().ToString(), out debit);
                    int.TryParse((woCells["I" + row].Value ?? "").ToString().ToString(), out remained);
                    wo.Ordered = ordered;
                    wo.Shipped = shipped;
                    wo.Debit = debit;
                    wo.Remained = remained;
                    wo.Closed = remained == 0 ? true : false;
                    wo.Active = true;

                    //Add to list
                    lstImportWO.Add(wo);

                    row++;
                }
                if (!success)
                {
                    Common.ShowErrorMess(error);
                }
                else
                {
                    SetImportState(true);
                    sourceWO.Clear();
                    sourceWO.DataSource = lstImportWO;
                    Common.SetNo(grvWO);
                }
            }
            catch (Exception ex)
            {
                Common.ShowErrorMess("btnImport_Click - " + ex.Message);
            }
        }
        
        private void btnExportTemp_Click(object sender, EventArgs e)
        {
            //Xuat file
            var saveFileDialog = new SaveFileDialog
            {
                FileName = "WOTemplate.xls"
            };

            if (saveFileDialog.ShowDialog() != DialogResult.OK)
            {
                return;
            }

            if (saveFileDialog.FileName.Equals(String.Empty))
            {
                return;
            }

            var fileName = saveFileDialog.FileName;
            
            //Mở file template cần đổ dữ liệu vào
            var stream = new MemoryStream(global::UnigenReport.Properties.Resources.WorldOrderTemplate);
            //Tạo một đối tượng workbook
            var workbook = new Workbook(stream);

            db = new UnigenDataContext();
            var cells = workbook.Worksheets[1].Cells;
            var product = db.Products.OrderBy(p => p.ProductName).ToList();
            var index = 2;
            foreach (var item in product)
            {
                cells["A" + index].Value = index -1;
                cells["B" + index].Value = item.ProductCode;
                cells["C" + index].Value = item.ProductName;
                cells["D" + index].Value = item.ProductNameVi;

                index++;
            }
            workbook.Save(fileName);

            //Mở file Excel vừa lưu
            System.Diagnostics.Process.Start(fileName);
        }

        private void btnCloseForm_Click(object sender, EventArgs e)
        {
            (this.Parent as Telerik.WinControls.UI.RadPageViewPage).Dispose();
        }

        private void btnSaveImport_Click(object sender, EventArgs e)
        {
            if (sourceWO.Count == 0)
            {
                Common.ShowNoticeMess("Không có dữ liệu mới!");
                SetImportState(false);
                BindData();
                return;
            }

            db = new UnigenDataContext();
            foreach(var item in (sourceWO.DataSource as List<WorldOrder>))
                db.WorldOrders.InsertOnSubmit(item.Clone());

            db.SubmitChanges();
            BindData();
            //menu
            SetImportState(false);
        }

        private void btnCancelImport_Click(object sender, EventArgs e)
        {
            BindData();
            //menu
            SetImportState(false);
        }
        
        private void btnSearch_Click(object sender, EventArgs e)
        {
            BindData();
        }

        private void btnExport_Click(object sender, EventArgs e)
        {
            var source = GetData();
            if (source.Count == 0) return;

            //Xuat file
            var saveFileDialog = new SaveFileDialog
            {
                FileName = String.Format("ListWO{0}.xls", DateTime.Now.ToString("yyyyMMddHHmmss"))
            };

            if (saveFileDialog.ShowDialog() != DialogResult.OK)
            {
                return;
            }

            if (saveFileDialog.FileName.Equals(String.Empty))
            {
                return;
            }

            var fileName = saveFileDialog.FileName;
            ExportFile(source, fileName, 0);
        }

        private void btnPrint_Click(object sender, EventArgs e)
        {
            var source = GetData();
            if (source.Count == 0) return;

            var dir = "Temp";
            if (!System.IO.File.Exists(dir))
                System.IO.Directory.CreateDirectory(dir);
            var fileName = String.Format("ListWO{0}.xls", DateTime.Now.ToString("yyyyMMddHHmmss"));
            ExportFile(source, dir + "\\" + fileName, 1);
        }

        private void grvWO_CellDoubleClick(object sender, GridViewCellEventArgs e)
        {
            Update();
        }

        #endregion
    }
}
